#ifndef __ATCH_TCP__
#define __ATCH_TCP__
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/errno.h>
#define true 1
#define bool int
#define false 0
typedef struct _TcpServerSession
{
    int clientfd;
    struct sockaddr_in clientAddr;
    socklen_t addrLen;
    pthread_t t;
    char buffer[1024];
    void (*serverSessionReceiveAction)(struct _TcpServerSession *);
    void (*serverSessionConnectedAction)(struct _TcpServerSession *);
    bool isConnected;
} TcpServerSession;

typedef struct _SocketTcpServer
{
    int16_t port;
    int serverfd;
    struct sockaddr_in serverAddr;

    pthread_t serverListenThread;
    TcpServerSession TcpServerSession;

    void (*serverSessionReceiveAction)(struct _TcpServerSession *);
    void (*serverSessionConnectedAction)(struct _TcpServerSession *);
} SocketTcpServer;

SocketTcpServer *create_tcp_server(int port, void (*tssra)(TcpServerSession *), void (*tssca)(TcpServerSession *));
void destroy_tcp_server(SocketTcpServer **sts);
void destroy_tcp_server_session(TcpServerSession **tss);
ssize_t tcp_server_session_sendmsg(TcpServerSession *tss, char msg[]);
typedef struct _TcpClientSession
{
    int32_t ip;
    int16_t port;

    int serverfd;
    socklen_t addrLen;

    char buffer[1024];

    struct sockaddr_in serverAddr;
    struct sockaddr_in clientAddr;

    pthread_t clientThread;

    void (*clientSessionConnectedAction)(struct _TcpClientSession *);
    void (*clientSessionReceiveAction)(struct _TcpClientSession *);
    bool isConnected;
} TcpClientSession;

TcpClientSession *create_tcp_client_session(char ip[], int port, void (*tcsra)(TcpClientSession *), void (*tcsca)(TcpClientSession *));
void destroy_tcp_client_session(TcpClientSession **tcs);
ssize_t tcp_client_session_sendmsg(TcpClientSession *tcs, char msg[], int msgLen);

void _tcp_server_callback(TcpServerSession *tss);
void _tcp_client_callback(TcpClientSession *tcs);
void _tcp_server_print(TcpServerSession *tss);
void _tcp_client_print(TcpClientSession *tcs);
#endif